<template>
  <div class="markdown-editor-box">
	  
    <link rel="stylesheet" href="/static/lib/editor.md-master/css/editormd.min.css">
    <div :id="editorId"></div>
  </div>
</template>

<script>
import scriptjs from 'scriptjs'
import { defaultConfig } from '@/src/config/MarkdownConfig.js'

export default {
  name: 'MarkdownEditor',
  props: {
    editorId: {
      type: String,
      default: 'markdown-editor'
    },
    onchange: {
      type: Function
    },
    config: {
      type: Object
    },
    initData: {
      type: String
    },
    initDataDelay: {
      type: Number,
      default: 0
    }
  },
  data () {
    return {
      editor: null,
      editorLoaded: false
    }
  },
  methods: {
    fetchScript (url) {
      return new Promise((resolve, reject) => {
        scriptjs(url, () => {
          resolve()
        })
      })
    },
    getConfig () {
      const baseConfig = {
        width: "100%",
        height: 640,
        path: "/static/lib/editor.md-master/lib/",
        theme: "default",
        previewTheme: "default",
        editorTheme: "default",
        markdown: "",
        codeFold: true,
        saveHTMLToTextarea: true,
        searchReplace: true,
        watch: true,
        htmlDecode: "style,script,iframe|on*",
        toolbar: true,
        toolbarIcons: "default",
        emoji: true,
        taskList: true,
        tocm: true,
        tex: true,
        flowChart: true,
        sequenceDiagram: true,
        imageUpload: true,
        imageFormats: ["jpg", "jpeg", "gif", "png", "bmp", "webp"],
        imageUploadURL: "/upload/image"
      }
      return { ...baseConfig, ...defaultConfig, ...this.config }
    },
    getEditor () {
      return this.editor
    },
    getDoc () {
      return this.doc
    },
    watch () {
      return this.editor.watch()
    },
    unwatch () {
      return this.editor.unwatch()
    },
    previewing () {
      return this.editor.previewing()
    },
    getHTML () {
      return this.editor.getHTML()
    },
    getMarkdown () {
      return this.editor.getMarkdown()
    },
    setMarkdown (markdown) {
      return this.editor.setMarkdown(markdown)
    },
    async loadDependencies() {
      try {
        // 加载jQuery
        await this.fetchScript('https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js')
        // 确保jQuery加载成功
        if (!window.jQuery) {
          throw new Error('jQuery加载失败')
        }
        
        // 加载editor.md
        await this.fetchScript('/static/lib/editor.md-master/editormd.min.js')
        // 确保editor.md加载成功
        if (!window.editormd) {
          throw new Error('editor.md加载失败')
        }
        
        return true
      } catch (error) {
        console.error('依赖加载失败:', error)
        return false
      }
    },
    async initEditor () {
      try {
        const loaded = await this.loadDependencies()
        if (!loaded) {
          throw new Error('依赖加载失败')
        }
        
        this.$nextTick(() => {
          try {
            const editor = window.editormd(this.editorId, this.getConfig())
            
            editor.on('load', () => {
              setTimeout(() => {
                this.editorLoaded = true
                if (this.initData) {
                  editor.setMarkdown(this.initData)
                }
              }, this.initDataDelay)
            })
            
            if (this.onchange) {
              editor.on('change', () => {
                const html = editor.getPreviewedHTML()
                this.onchange({
                  markdown: editor.getMarkdown(),
                  html: html,
                  text: window.$(html).text()
                })
              })
            }
            
            this.editor = editor
          } catch (error) {
            console.error('编辑器初始化失败:', error)
            throw error
          }
        })
      } catch (error) {
        console.error('编辑器初始化失败:', error)
        uni.showToast({
          title: '编辑器加载失败',
          icon: 'none'
        })
      }
    }
  },
  mounted () {
    this.initEditor()
  },
  watch: {
    initData: function (newVal) {
      if (newVal && this.editorLoaded && this.editor) {
        this.editor.setMarkdown(newVal)
      }
    }
  }
}
</script>

<style scoped lang="less">
.markdown-editor-box {
  width: 100%;
  height: 100%;
}
</style>

